package com.onlyxiahui.common.util;

import java.io.File;
import java.lang.reflect.Modifier;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.CodeSource;
import java.security.ProtectionDomain;

public class OnlyClassUtil {

	/**
	 * 输入Class类，返回所在的jar路径
	 * 
	 * @param clazz
	 * @return URL
	 */
	public static URL getClassLocation(final Class<?> clazz) {
		if (clazz == null) {
			throw new IllegalArgumentException("null input: clazz");
		}
		URL result = null;
		final String clsAsResource = clazz.getName().replace('.', '/').concat(".class");
		final ProtectionDomain pd = clazz.getProtectionDomain();
		// java.lang.Class contract does not specify if 'pd' can ever be null;
		// it is not the case for Sun's implementations, but guard against null
		// just in case:
		if (pd != null) {
			final CodeSource cs = pd.getCodeSource();
			// 'cs' can be null depending on the classloader behavior:
			if (cs != null) {
				result = cs.getLocation();
			}
			if (result != null) {
				// Convert a code source location into a full class file
				// location
				// for some common cases:
				if ("file".equals(result.getProtocol())) {
					try {
						if (result.toExternalForm().endsWith(".jar") || result.toExternalForm().endsWith(".zip")) {
							result = new URL("jar:".concat(result.toExternalForm()).concat("!/").concat(clsAsResource));
						} else if (new File(result.getFile()).isDirectory()) {
							result = new URL(result, clsAsResource);
						}
					} catch (MalformedURLException ignore) {
					}
				}
			}
		}
		if (result == null) {
			// Try to find 'cls' definition as a resource; this is not
			// document．d to be legal, but Sun's implementations seem to //allow
			// this:
			final ClassLoader clsLoader = clazz.getClassLoader();
			result = clsLoader != null ? clsLoader.getResource(clsAsResource) : ClassLoader.getSystemResource(clsAsResource);
		}
		return result;
	}

	/**
	 * 是否可被实例化<br>
	 * date: 2017-05-1 4:30:43
	 * 
	 * @param classType
	 * @return boolean
	 */
	public static boolean isCanInstance(Class<?> classType) {
		boolean can = true;
		if (classType.isAnnotation()) {
			can = false;
		}
		if (classType.isArray()) {
			can = false;
		}
		if (classType.isEnum()) {
			can = false;
		}
		if (classType.isInterface()) {
			can = false;
		}
		boolean isAbstract = Modifier.isAbstract(classType.getModifiers());
		if (isAbstract) {
			can = false;
		}
		return can;
	}
}
